package list.model;

import list.control.MysqlLink;
import list.control.Searcher;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 * Created by ZhipengLi.
 */
public class Contact extends MysqlLink {
    private static final String TABLE = "contact";

    private int contact_id;

    private int user_id;

    private String name;

    private String nickname;

    private String email;

    private String birthday;

    private String head;

    private String work_place;

    private String postcode;

    private String address;

    private int tag_id;

    private String wechat;

    private String qq;

    private String alipay;

    private Contact(int contact_id, int user_id, String name, String nickname, String email, String birthday, String head, String work_place, String postcode, String address, int tag_id, String wechat, String qq, String alipay) {
        this.contact_id = contact_id;
        this.user_id = user_id;
        this.name = name;
        this.nickname = nickname;
        this.email = email;
        this.birthday = birthday;
        this.head = head;
        this.work_place = work_place;
        this.postcode = postcode;
        this.address = address;
        this.tag_id = tag_id;
        this.wechat = wechat;
        this.qq = qq;
        this.alipay = alipay;
    }

    public static boolean insert(int user_id, int tag_id) {
        return insert(TABLE, toArray("user_id", "tag_id", "name"), toArray(user_id, tag_id, "NEW FRIEND")) && Tag.increase(user_id, tag_id);
    }

    static boolean delete(int user_id, int tag_id, int contact_id) {
        Telephone.delete(contact_id);
        return delete(TABLE, equalsAnd(toArray("user_id", "tag_id", "contact_id"), toArray(user_id, tag_id, contact_id))) && Tag.decrease(user_id, tag_id);
    }

    static boolean delete(int tag_id) {
        Integer[] user_ids = getUserIds(tag_id);
        if (null != user_ids) {
            for (Integer id : user_ids) {
                Telephone.delete(id);
            }
        }
        return delete(TABLE, equal("tag_id", tag_id));
    }

    public static boolean update(int user_id, int contact_id, String property, Object value) {
        String[] fields = {"name", "nickname", "email", "birthday", "head", "work_place", "postcode", "address", "tag_id", "wechat", "qq", "alipay"};
        for (String field : fields) {
            if (field.equals(property)) {
                return update(TABLE, property, value, equalsAnd(toArray("user_id", "contact_id"), toArray(user_id, contact_id)));
            }
        }
        return false;
    }

    public static boolean update(int contact_id, String nickname, String birthday, String head, String work_place, String postcode, String wechat, String qq, String alipay) {
        return update(TABLE, toArray("nickname", "birthday", "head", "work_place", "postcode", "wechat", "qq", "alipay"), toArray(nickname, birthday, head, work_place, postcode, wechat, qq, alipay), equal("contact_id", contact_id));
    }

    public static Contact[] select(int user_id, int tag_id) {
        ResultSet resultSet = select(TABLE, ALL, equalsAnd(toArray("user_id", "tag_id"), toArray(user_id, tag_id)));
        return resultOfSelect(resultSet);
    }

    public static Contact[] select(int user_id) {
        ResultSet resultSet = select(TABLE, ALL, equal("user_id", user_id));
        return resultOfSelect(resultSet);
    }

    private static Integer[] getUserIds(int tag_id) {
        ArrayList<Integer> output = new ArrayList<>();
        ResultSet resultSet = select(TABLE, "id", equal("tag_id", tag_id));
        if (null != resultSet) {
            try {
                while (resultSet.next()) {
                    output.add(resultSet.getInt("id"));
                }
                resultSet.close();
                if (0 < output.size()) {
                    Integer[] result = new Integer[output.size()];
                    output.toArray(result);
                    return result;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static boolean isExisted(int user_id, int tag_id, String name) {
        return exist(TABLE, "id", equalsAnd(toArray("user_id", "tag_id", "name"), toArray(user_id, tag_id, name)));
    }

    private static Contact[] resultOfSelect(ResultSet resultSet) {
        if (null != resultSet) {
            try {
                ArrayList<Contact> contacts = new ArrayList<>();
                while (resultSet.next()) {
                    int contact_id = resultSet.getInt("contact_id");
                    int user_id = resultSet.getInt("user_id");
                    int tag_id = resultSet.getInt("tag_id");
                    String name = resultSet.getString("name");
                    String nickname = resultSet.getString("nickname");
                    String email = resultSet.getString("email");
                    String birthday = resultSet.getString("birthday");
                    String head = resultSet.getString("head");
                    String work_place = resultSet.getString("work_place");
                    String postcode = resultSet.getString("postcode");
                    String address = resultSet.getString("address");
                    String wechat = resultSet.getString("wechat");
                    String qq = resultSet.getString("qq");
                    String alipay = resultSet.getString("alipay");
                    contacts.add(new Contact(contact_id, user_id, name, nickname, email, birthday, head, work_place, postcode, address, tag_id, wechat, qq, alipay));
                }
                resultSet.close();
                if (0 < contacts.size()) {
                    Contact[] contactList = new Contact[contacts.size()];
                    contacts.toArray(contactList);
                    return contactList;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private static Contact[] resultOfSearch(Contact[] contacts) {
        int size = 0;
        for (Contact contact : contacts) {
            if (contact != null) {
                size++;
            }
        }
        Contact[] output = new Contact[size];
        System.arraycopy(contacts, 0, output, 0, size);
        return output;
    }

    public static Contact[] searchName(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getNameList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByName(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getNameList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            output[i] = contacts[i].getName();
        }
        return output;
    }

    private static Contact selectByName(Contact[] all, String value) {
        for (Contact contact : all) {
            if (contact.getName().equals(value)) {
                return contact;
            }
        }
        return null;
    }

    public static Contact[] searchNickname(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getNicknameList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByNickname(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getNicknameList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            String value = contacts[i].getNickname();
            if (value != null) {
                output[i] = value;
            } else {
                output[i] = "";
            }
        }
        return output;
    }

    private static Contact selectByNickname(Contact[] all, String value) {
        for (Contact contact : all) {
            if (null != contact.getNickname()) {
                if (contact.getNickname().equals(value)) {
                    return contact;
                }
            }
        }
        return null;
    }


    public static Contact[] searchEmail(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getEmailList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByEmail(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getEmailList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            String value = contacts[i].getEmail();
            if (value != null) {
                output[i] = value;
            } else {
                output[i] = "";
            }
        }
        return output;
    }

    private static Contact selectByEmail(Contact[] all, String value) {
        for (Contact contact : all) {
            if (null != contact.getEmail()) {
                if (contact.getEmail().equals(value)) {
                    return contact;
                }
            }
        }
        return null;
    }

    public static Contact[] searchBirthday(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getBirthdayList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByBirthday(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getBirthdayList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            String value = contacts[i].getBirthday();
            if (value != null) {
                output[i] = value;
            } else {
                output[i] = "";
            }
        }
        return output;
    }

    private static Contact selectByBirthday(Contact[] all, String value) {
        for (Contact contact : all) {
            if (null != contact.getBirthday()) {
                if (contact.getBirthday().equals(value)) {
                    return contact;
                }
            }
        }
        return null;
    }

    public static Contact[] searchPostcode(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getPostcodeList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByPost(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getPostcodeList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            String value = contacts[i].getPostcode();
            if (value != null) {
                output[i] = value;
            } else {
                output[i] = "";
            }
        }
        return output;
    }

    private static Contact selectByPost(Contact[] all, String value) {
        for (Contact contact : all) {
            if (null != contact.getPostcode()) {
                if (contact.getPostcode().equals(value)) {
                    return contact;
                }
            }
        }
        return null;
    }

    public static Contact[] searchWork_Place(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getWork_PlaceList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByWork_Place(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getWork_PlaceList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            String value = contacts[i].getWork_place();
            if (value != null) {
                output[i] = value;
            } else {
                output[i] = "";
            }
        }
        return output;
    }

    private static Contact selectByWork_Place(Contact[] all, String value) {
        for (Contact contact : all) {
            if (null != contact.getWork_place()) {
                if (contact.getWork_place().equals(value)) {
                    return contact;
                }
            }
        }
        return null;
    }

    public static Contact[] searchAddress(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getAddressList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByAddress(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getAddressList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            String value = contacts[i].getAddress();
            if (value != null) {
                output[i] = value;
            } else {
                output[i] = "";
            }
        }
        return output;
    }

    private static Contact selectByAddress(Contact[] all, String value) {
        for (Contact contact : all) {
            if (null != contact.getAddress()) {
                if (contact.getAddress().equals(value)) {
                    return contact;
                }
            }
        }
        return null;
    }

    public static Contact[] searchWechat(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getWechatList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByWechat(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getWechatList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            String value = contacts[i].getWechat();
            if (value != null) {
                output[i] = value;
            } else {
                output[i] = "";
            }
        }
        return output;
    }

    private static Contact selectByWechat(Contact[] all, String value) {
        for (Contact contact : all) {
            if (null != contact.getWechat()) {
                if (contact.getWechat().equals(value)) {
                    return contact;
                }
            }
        }
        return null;
    }

    public static Contact[] searchQq(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getQqList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByQq(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getQqList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            String value = contacts[i].getQq();
            if (value != null) {
                output[i] = value;
            } else {
                output[i] = "";
            }
        }
        return output;
    }

    private static Contact selectByQq(Contact[] all, String value) {
        for (Contact contact : all) {
            if (null != contact.getQq()) {
                if (contact.getQq().equals(value)) {
                    return contact;
                }
            }
        }
        return null;
    }

    public static Contact[] searchAlipay(int user_id, String content, int count) {
        Contact[] all = select(user_id);
        String[] result = Searcher.simpleMatch(content, getAlipayList(all));
        Contact[] output = new Contact[count];
        for (int i = 0; i < count && i < all.length; i++) {
            output[i] = selectByAlipay(all, result[i]);
        }
        return resultOfSearch(output);
    }

    private static String[] getAlipayList(Contact[] contacts) {
        int length = contacts.length;
        String[] output = new String[length];
        for (int i = 0; i < length; i++) {
            String value = contacts[i].getAlipay();
            if (value != null) {
                output[i] = value;
            } else {
                output[i] = "";
            }
        }
        return output;
    }

    private static Contact selectByAlipay(Contact[] all, String value) {
        for (Contact contact : all) {
            if (null != contact.getAlipay()) {
                if (contact.getAlipay().equals(value)) {
                    return contact;
                }
            }
        }
        return null;
    }


    public Telephone[] getTelephones() {
        return Telephone.select(contact_id);
    }

    public int getContact_id() {
        return contact_id;
    }

    public int getUser_id() {
        return user_id;
    }

    public String getName() {
        return name;
    }

    public String getNickname() {
        return nickname;
    }

    public String getEmail() {
        return email;
    }

    public String getBirthday() {
        return birthday;
    }

    public String getHead() {
        return head;
    }

    public String getWork_place() {
        return work_place;
    }

    public String getPostcode() {
        return postcode;
    }

    public String getAddress() {
        return address;
    }

    public int getTag_id() {
        return tag_id;
    }

    public String getWechat() {
        return wechat;
    }

    public String getQq() {
        return qq;
    }

    public String getAlipay() {
        return alipay;
    }

}
